package com.zjw.algorithm.epoll_mock;

import java.util.Comparator;
import java.util.PriorityQueue;

public class SimpleEventQueue implements IEventQueue {

    private final PriorityQueue<Event> mReadyEvent = new PriorityQueue<>(Comparator.comparingLong(o -> o.time));

    @Override
    public void enqueue(Event event) {
        if (event.time > 0) {
            event.systemTime = System.currentTimeMillis() + event.time;
        }
        synchronized (mReadyEvent) {
            mReadyEvent.offer(event);
        }
        notifyWork();
    }

    private void notifyWork() {
        synchronized (this) {
            this.notifyAll();
        }
    }

    @Override
    public Event waitEvent() {
        while (true) {
            Event firstEvent;
            synchronized (mReadyEvent) {
                firstEvent = mReadyEvent.peek();
            }
            long time = 0L;
            if (firstEvent != null && firstEvent.time > 0) {
                time = Math.max(1L, firstEvent.systemTime - System.currentTimeMillis());
            }

            try {
                synchronized (this) {
                    this.wait(time);
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized (mReadyEvent) {
                if (mReadyEvent.isEmpty()) {
                    continue;
                }
                Event peek = mReadyEvent.peek();
                if (peek.systemTime <= System.currentTimeMillis()) {
                    return mReadyEvent.poll();
                }
            }
        }
    }
}
